/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "3D控制手柄.h"
#include "物体编辑/物体编辑.h"

#include <matXX.h>
#include <几何图形/图形相交.h>
#include <异步解算/物理异步解算.h>
#include <物体/S_摄像机.h>

#include "框架/视口元素.h"




static std::vector<S_物体*> g要变换的物体;
static std::vector<Mat44f>	g要变换的物体暂存矩阵;
static std::vector<Mat44f>	g要旋转的物体暂存矩阵;
static std::vector<Mat44f>	g要变换的物体缩放矩阵暂存;

static std::vector<vec3>	g要变换的物体暂存全局坐标;
static std::vector<vec3>	g要变换的物体暂存位置;
static std::vector<vec3>	g要变换的物体暂存旋转;
static std::vector<vec3>	g要变换的物体暂存缩放;
static std::vector<vec4>	g要变换的物体暂存quat;

static float32				g记录初始步进 = 0;
static S_Tranform			g手柄初始变换 = {};

static bool g开启变换 = false;



Inline vec3 f_顶点坐标移动变换(const Mat44f& 模型矩阵, const Mat44f& 模型逆矩阵, const vec3& 手柄要移动到是位置, const vec3& vert) {
	vec3 tv = 模型矩阵 * vert;
	return 模型逆矩阵 * (手柄要移动到是位置 + (tv - g手柄初始变换.position));
}
Inline vec3 f_顶点坐标旋转变换(const Mat44f& 模型矩阵, const Mat44f& 模型逆矩阵, const vec4& rot_q, const vec3& vert) {
	vec3 tv = 模型矩阵 * vert;

	vec3 移动矢量 = (f_graph_quat变换坐标(rot_q, tv - g手柄初始变换.position));
	return 模型逆矩阵 * (g手柄初始变换.position + 移动矢量);
}



static E_轴向 f_手柄拾取_移动手柄(S_物体* 手柄, const vec2& 拾取坐标, const S_Rect2Df& rect, const vec3& s, const vec3& dir, const S_摄像机& camera) {
	float32 拾取线距离 = 20;

	S_线拾取 线拾取 = { {}, 100000000 , 100000000, -1 };
	Mat44f mat[4] = { f_ob_get变换矩阵(手柄, 0), camera.m_相机投影矩阵, camera.m_相机视图矩阵, camera.m_相机逆矩阵};


	auto& 轴线X = f_ob_get数据(手柄, 0);
	auto& 轴线Y = f_ob_get数据(手柄, 1);
	auto& 轴线Z = f_ob_get数据(手柄, 2);

	auto& X箭头 = f_ob_get数据(手柄, 3);
	auto& Y箭头 = f_ob_get数据(手柄, 4);
	auto& Z箭头 = f_ob_get数据(手柄, 5);

	auto& 中心点 = f_ob_get数据(手柄, 6);
	auto& 中心圈 = f_ob_get数据(手柄, 7);

	auto& 平面XY = f_ob_get数据(手柄, 8);
	auto& 平面XZ = f_ob_get数据(手柄, 9);
	auto& 平面YZ = f_ob_get数据(手柄, 10);

	auto 轴线拾取信息X = f_surface_屏幕拾取线段(轴线X.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 轴线拾取信息Y = f_surface_屏幕拾取线段(轴线Y.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 轴线拾取信息Z = f_surface_屏幕拾取线段(轴线Z.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);

	auto X箭头拾取信息 = f_surface_射线面相交(X箭头.m_Mesh, mat, s, dir);
	auto Y箭头拾取信息 = f_surface_射线面相交(Y箭头.m_Mesh, mat, s, dir);
	auto Z箭头拾取信息 = f_surface_射线面相交(Z箭头.m_Mesh, mat, s, dir);
	auto 视线轴点拾取信息 = f_surface_屏幕拾取点(中心点.m_Mesh, mat, 拾取坐标, rect, 12);

	//std::cout<<"轴线拾取信息.相交宽度 = "<<视线轴点拾取信息.相交宽度<< " " << 轴线拾取信息.相交宽度 << std::endl;
	auto 平面XY拾取信息 = f_surface_射线面相交(平面XY.m_Mesh, mat, s, dir);
	auto 平面XZ拾取信息 = f_surface_射线面相交(平面XZ.m_Mesh, mat, s, dir);
	auto 平面YZ拾取信息 = f_surface_射线面相交(平面YZ.m_Mesh, mat, s, dir);


	auto& push_轴线X = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线X.m_常量推送);
	push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);
	auto& push_轴线Y = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线Y.m_常量推送);
	push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_轴线Z = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线Z.m_常量推送);
	push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);


	auto& push_X箭头 = f_df_推送常量<S_ConstPush_Mesh_Face>(X箭头.m_常量推送);
	push_X箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);
	auto& push_Y箭头 = f_df_推送常量<S_ConstPush_Mesh_Face>(Y箭头.m_常量推送);
	push_Y箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_Z箭头 = f_df_推送常量<S_ConstPush_Mesh_Face>(Z箭头.m_常量推送);
	push_Z箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);


	auto& push_中心圈 = f_df_推送常量<S_ConstPush_Mesh_Line>(中心圈.m_常量推送);
	push_中心圈.m_Ob_Color = f_PackData4X8(S_RGBA8UI{ 140, 140, 140, 255 });

	auto& push_平面XY = f_df_推送常量<S_ConstPush_Mesh_Face>(平面XY.m_常量推送);
	push_平面XY.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);
	auto& push_平面XZ = f_df_推送常量<S_ConstPush_Mesh_Face>(平面XZ.m_常量推送);
	push_平面XZ.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_平面YZ = f_df_推送常量<S_ConstPush_Mesh_Face>(平面YZ.m_常量推送);
	push_平面YZ.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);


	float32 拾取最小距离 = DEF_PickUp_LineDis;
	float32 面拾取最小距离 = DEF_PickUp_LineMaxDis;
	S_RGBA8UI 亮度 = S_RGBA8UI{ 100, 100, 100, 10 };

	E_轴向 拾取轴向 = E_轴向::e_None轴向;
	if (轴线拾取信息X.线索引 >= 0 && 轴线拾取信息X.相交宽度 < 拾取最小距离) {
		push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
		push_X箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
		拾取最小距离 = 轴线拾取信息X.相交宽度;
		拾取轴向 = E_轴向::e_X;
	}
	if (轴线拾取信息Y.线索引 >= 0 && 轴线拾取信息Y.相交宽度 < 拾取最小距离) {
		push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
		push_Y箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
		拾取最小距离 = 轴线拾取信息Y.相交宽度;
		拾取轴向 = E_轴向::e_Y;
	}
	if (轴线拾取信息Z.线索引 >= 0 && 轴线拾取信息Z.相交宽度 < 拾取最小距离) {
		push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
		push_Z箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
		拾取最小距离 = 轴线拾取信息Z.相交宽度;
		拾取轴向 = E_轴向::e_Z;
	}


	if (视线轴点拾取信息.点索引 >= 0 && 视线轴点拾取信息.相交宽度 <= 拾取最小距离) {
		push_中心圈.m_Ob_Color = f_PackData4X8(S_RGBA8UI{ 220, 220, 220, 255 });
		拾取轴向 = E_轴向::e_XYZ;
	}


	if (拾取轴向 == E_轴向::e_None轴向) {
		if (平面XY拾取信息.相交宽度 < 面拾取最小距离) {
			push_平面XY.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
			面拾取最小距离 = 平面XY拾取信息.相交宽度;
			拾取轴向 = E_轴向::e_XY;
		}
		if (平面XZ拾取信息.相交宽度 < 面拾取最小距离) {
			push_平面XZ.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
			面拾取最小距离 = 平面XZ拾取信息.相交宽度;
			拾取轴向 = E_轴向::e_XZ;
		}
		if (平面YZ拾取信息.相交宽度 < 面拾取最小距离) {
			push_平面YZ.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
			面拾取最小距离 = 平面YZ拾取信息.相交宽度;
			拾取轴向 = E_轴向::e_YZ;
		}


		if (X箭头拾取信息.相交宽度 < 拾取最小距离) {
			push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
			push_X箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
			拾取最小距离 = X箭头拾取信息.相交宽度;
			拾取轴向 = E_轴向::e_X;
		}
		if (Y箭头拾取信息.相交宽度 < 拾取最小距离) {
			push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
			push_Y箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
			拾取最小距离 = Y箭头拾取信息.相交宽度;
			拾取轴向 = E_轴向::e_Y;
		}
		if (Z箭头拾取信息.相交宽度 < 拾取最小距离) {
			push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
			push_Z箭头.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
			拾取最小距离 = Z箭头拾取信息.相交宽度;
			拾取轴向 = E_轴向::e_Z;
		}
	}

	//if (拾取轴向 != E_轴向::e_None轴向) S_框架::g_物体变换方式	= E_变换::e_移动;
	return 拾取轴向;
}

static E_轴向 f_手柄拾取_旋转手柄(S_物体* 手柄, const vec2& 拾取坐标, const S_Rect2Df& rect, const vec3& s, const vec3& dir, const S_摄像机& camera) {
	float32 拾取线距离 = 20;

	S_线拾取 线拾取 = { {}, 100000000 , 100000000, -1 };
	Mat44f mat[4] = { f_ob_get变换矩阵(手柄, 0), camera.m_相机投影矩阵, camera.m_相机视图矩阵, camera.m_相机逆矩阵};


	auto& 轴线X = f_ob_get数据(手柄, 0);
	auto& 轴线Y = f_ob_get数据(手柄, 1);
	auto& 轴线Z = f_ob_get数据(手柄, 2);

	auto& 外圈 = f_ob_get数据(手柄, 3);

	auto 轴线拾取信息X = f_surface_正面拾取屏幕线段(轴线X.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 轴线拾取信息Y = f_surface_正面拾取屏幕线段(轴线Y.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 轴线拾取信息Z = f_surface_正面拾取屏幕线段(轴线Z.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 外圈拾取信息 = f_surface_屏幕拾取线段(外圈.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);

	auto& push_轴线X = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线X.m_常量推送);
	push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);
	auto& push_轴线Y = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线Y.m_常量推送);
	push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_轴线Z = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线Z.m_常量推送);
	push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);
	auto& push_中心圈 = f_df_推送常量<S_ConstPush_Mesh_Line>(外圈.m_常量推送);
	push_中心圈.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_C);


	float32 拾取最小距离 = DEF_PickUp_LineDis;
	S_RGBA8UI 亮度 = S_RGBA8UI{ 100, 100, 100, 10 };

	E_轴向 拾取轴向 = E_轴向::e_None轴向;
	if (外圈拾取信息.线索引 >= 0 && 外圈拾取信息.相交宽度 < 拾取最小距离) {
		push_中心圈.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_C + 亮度);
		拾取最小距离 = 外圈拾取信息.相交宽度;
		拾取轴向 = E_轴向::e_XYZ;
	}
	if (轴线拾取信息X.线索引 >= 0 && 轴线拾取信息X.相交宽度 < 拾取最小距离) {
		push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
		拾取最小距离 = 轴线拾取信息X.相交宽度;
		拾取轴向 = E_轴向::e_X;
	}
	if (轴线拾取信息Y.线索引 >= 0 && 轴线拾取信息Y.相交宽度 < 拾取最小距离) {
		push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
		拾取最小距离 = 轴线拾取信息Y.相交宽度;
		拾取轴向 = E_轴向::e_Y;
	}
	if (轴线拾取信息Z.线索引 >= 0 && 轴线拾取信息Z.相交宽度 < 拾取最小距离) {
		push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
		拾取最小距离 = 轴线拾取信息Z.相交宽度;
		拾取轴向 = E_轴向::e_Z;
	}

	//if (拾取轴向 != E_轴向::e_None轴向) S_框架::g_物体变换方式	= E_变换::e_旋转;
	return 拾取轴向;
}


static E_轴向 f_手柄拾取_缩放手柄(S_物体* 手柄, const vec2& 拾取坐标, const S_Rect2Df& rect, const vec3& s, const vec3& dir, const S_摄像机& camera) {
	float32 拾取线距离 = 20;

	S_线拾取 线拾取 = { {}, 100000000 , 100000000, -1 };
	Mat44f mat[4] = { f_ob_get变换矩阵(手柄, 0), camera.m_相机投影矩阵, camera.m_相机视图矩阵, camera.m_相机逆矩阵};

	auto& 轴线X = f_ob_get数据(手柄, 1);
	auto& 轴线Y = f_ob_get数据(手柄, 2);
	auto& 轴线Z = f_ob_get数据(手柄, 3);

	auto& 点X = f_ob_get数据(手柄, 4);
	auto& 点Y = f_ob_get数据(手柄, 5);
	auto& 点Z = f_ob_get数据(手柄, 6);

	auto& 外圈 = f_ob_get数据(手柄, 7);

	auto& 平面XY = f_ob_get数据(手柄, 9);
	auto& 平面XZ = f_ob_get数据(手柄, 10);
	auto& 平面YZ = f_ob_get数据(手柄, 11);


	auto& push_轴线X = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线X.m_常量推送);
	push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);
	auto& push_轴线Y = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线Y.m_常量推送);
	push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_轴线Z = f_df_推送常量<S_ConstPush_Mesh_Line>(轴线Z.m_常量推送);
	push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);
	auto& push_点X = f_df_推送常量<S_ConstPush_Mesh_Point>(点X.m_常量推送);
	push_点X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);
	auto& push_点Y = f_df_推送常量<S_ConstPush_Mesh_Point>(点Y.m_常量推送);
	push_点Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_点Z = f_df_推送常量<S_ConstPush_Mesh_Point>(点Z.m_常量推送);
	push_点Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);
	auto& push_中心圈 = f_df_推送常量<S_ConstPush_Mesh_Line>(外圈.m_常量推送);
	push_中心圈.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_C);

	auto& push_平面XY = f_df_推送常量<S_ConstPush_Mesh_Face>(平面XY.m_常量推送);
	push_平面XY.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B);
	auto& push_平面XZ = f_df_推送常量<S_ConstPush_Mesh_Face>(平面XZ.m_常量推送);
	push_平面XZ.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G);
	auto& push_平面YZ = f_df_推送常量<S_ConstPush_Mesh_Face>(平面YZ.m_常量推送);
	push_平面YZ.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R);


	auto 轴线拾取信息X = f_surface_屏幕拾取线段(轴线X.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 轴线拾取信息Y = f_surface_屏幕拾取线段(轴线Y.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	auto 轴线拾取信息Z = f_surface_屏幕拾取线段(轴线Z.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);
	
	auto 点拾取信息X = f_surface_屏幕拾取点(点X.m_Mesh, mat, 拾取坐标, rect, DEF_手柄端点大小);
	auto 点拾取信息Y = f_surface_屏幕拾取点(点Y.m_Mesh, mat, 拾取坐标, rect, DEF_手柄端点大小);
	auto 点拾取信息Z = f_surface_屏幕拾取点(点Z.m_Mesh, mat, 拾取坐标, rect, DEF_手柄端点大小);

	auto 外圈拾取信息 = f_surface_屏幕拾取线段(外圈.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineDis);

	auto 平面XY拾取信息 = f_surface_屏幕拾取线段(平面XY.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineMaxDis);
	auto 平面XZ拾取信息 = f_surface_屏幕拾取线段(平面XZ.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineMaxDis);
	auto 平面YZ拾取信息 = f_surface_屏幕拾取线段(平面YZ.m_Mesh, mat, 拾取坐标, rect, DEF_PickUp_LineMaxDis);


	float32 拾取最小距离 = DEF_PickUp_LineDis;
	S_RGBA8UI 亮度 = S_RGBA8UI{ 100, 100, 100, 10 };

	E_轴向 拾取轴向 = E_轴向::e_None轴向;
	if (外圈拾取信息.线索引 >= 0 && 外圈拾取信息.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 外圈拾取信息.相交宽度;
		拾取轴向 = E_轴向::e_XYZ;
	}
	if (轴线拾取信息X.线索引 >= 0 && 轴线拾取信息X.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 轴线拾取信息X.相交宽度;
		拾取轴向 = E_轴向::e_X;
	}
	if (轴线拾取信息Y.线索引 >= 0 && 轴线拾取信息Y.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 轴线拾取信息Y.相交宽度;
		拾取轴向 = E_轴向::e_Y;
	}
	if (轴线拾取信息Z.线索引 >= 0 && 轴线拾取信息Z.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 轴线拾取信息Z.相交宽度;
		拾取轴向 = E_轴向::e_Z;
	}

	if (点拾取信息X.点索引 >= 0 && 点拾取信息X.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 点拾取信息X.相交宽度;
		拾取轴向 = E_轴向::e_X;
	}
	if (点拾取信息Y.点索引 >= 0 && 点拾取信息Y.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 点拾取信息Y.相交宽度;
		拾取轴向 = E_轴向::e_Y;
	}
	if (点拾取信息Z.点索引 >= 0 && 点拾取信息Z.相交宽度 < 拾取最小距离) {
		拾取最小距离 = 点拾取信息Z.相交宽度;
		拾取轴向 = E_轴向::e_Z;
	}

	switch (拾取轴向) {
		case E_轴向::e_XYZ: {
			push_中心圈.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_C + 亮度);
			break;
		}
		case E_轴向::e_X: {
			push_轴线X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
			push_点X.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_R + 亮度);
			break;
		}
		case E_轴向::e_Y: {
			push_轴线Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
			push_点Y.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_G + 亮度);
			break;
		}
		case E_轴向::e_Z: {
			push_轴线Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
			push_点Z.m_Ob_Color = f_PackData4X8(S_主题颜色::uic_B + 亮度);
			break;
		}
		default:
			break;
	}
	return 拾取轴向;
}


E_轴向 f_变换手柄_拾取(S_物体* 手柄, const vec2& 拾取坐标, const S_Rect2Df& rect, const vec3& s, const vec3& dir, const S_摄像机& camera) {
	
	E_轴向 拾取轴向 = E_轴向::e_None轴向;

	switch (S_框架::g_变换手柄类型) {
		case E_变换::e_移动: {
			拾取轴向 = f_手柄拾取_移动手柄(手柄, 拾取坐标, rect, s, dir, camera);
			break;
		}
		case E_变换::e_旋转: {
			拾取轴向 = f_手柄拾取_旋转手柄(手柄, 拾取坐标, rect, s, dir, camera);
			break;
		}
		case E_变换::e_缩放: {
			拾取轴向 = f_手柄拾取_缩放手柄(手柄, 拾取坐标, rect, s, dir, camera);
			break;
		}
		default:
			break;
	}

	return 拾取轴向;
}





bool f_控制手柄_准备变换(bool 重启) {
	if(重启) g开启变换 = false;
	if(g开启变换) return false;


	g要变换的物体.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体暂存矩阵.clear();
	g要变换的物体暂存全局坐标.clear();

	g要旋转的物体暂存矩阵.clear();
	g要变换的物体暂存旋转.clear();
	g要变换的物体暂存quat.clear();

	f_projectFile_设置文件保存状态(false);
	S_节点数据::g_开启节点更新 = false;


	
	return true;
}




void f_变换_准备移动物体(S_物体* 手柄, bool 强制重启) {
	//if(f_控制手柄_准备变换() == false && 强制重启) return;
	f_控制手柄_准备变换();

	g手柄初始变换 = 手柄->m_变换;
	std::cout<<" x = " << g手柄初始变换.position.x <<" y = " << g手柄初始变换.position.y <<" z = " << g手柄初始变换.position.z << std::endl;

	g要变换的物体.clear();
	g要变换的物体暂存位置.clear();

	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		for (auto 编辑物体 : S_节点数据::g_编辑物体) {
			g要变换的物体.push_back(编辑物体);
		}

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				for (auto& e : S_框架::g_选择端点) {
					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								g要变换的物体暂存位置.push_back(point[i.x].value);
								g要变换的物体暂存位置.push_back(point[i.x].L_point);
								g要变换的物体暂存位置.push_back(point[i.x].R_point);
								break;
							}
							case 1: {
								g要变换的物体暂存位置.push_back(point[i.x].L_point);
								break;
							}
							case 2: {
								g要变换的物体暂存位置.push_back(point[i.x].R_point);
								break;
							}
						}
					}
				}
				break;
			}
		}
	}
	else {
		
		g要变换的物体暂存旋转.clear();
		g要变换的物体暂存矩阵.clear();
		g要变换的物体暂存全局坐标.clear();


		for (auto* ob : S_框架::g_拾取物体) {
			g要变换的物体.push_back(ob);

			g要变换的物体暂存位置.push_back(ob->f_get位置());
			if (ob->m_父对象) {
				Mat44f mat = f_ob_get父对象变换矩阵(static_cast<S_物体*>(ob->m_父对象), 0);
				g要变换的物体暂存矩阵.push_back(mat);
			}
			else {
				g要变换的物体暂存矩阵.push_back(f_mat44_identity());
			}

			g要变换的物体暂存全局坐标.push_back(f_ob_get全局坐标(ob, ob->m_实例ID));
		}
		f_OE_准备变换( S_框架::g_拾取物体, E_变换::e_移动);
	}


	for (auto& e : S_框架::g_插件_变换操作) {
		if(e.second.mf_开始) e.second.mf_开始(S_框架::g_物体变换方式);
	}
}

void f_变换_移动物体(const vec3& 手柄要移动到是位置) {
	//S_框架::g_移动变换手柄->f_set位置(手柄要移动到是位置, 0);
	g开启变换 = true;

	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* 全局坐标 = g要变换的物体暂存全局坐标.data();
	auto* mat = g要变换的物体暂存矩阵.data();

	for (int32 i = 0; i < num; ++i) {
		if(ob[i]->m_销毁) continue;

		Mat44f m;
		if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
			switch (S_框架::g当前编辑对象类型) {
				case E_物体类型::t_空间曲线: {
					uint32 offset = 0;

					for (auto& e : S_框架::g_选择端点) {
						m = f_ob_get变换矩阵(e.first, e.first->m_实例ID);
						auto iv_m = f_mat44_Invert(m);

						auto* me = f_ob_getMesh(e.first);
						auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);


						for (auto& i : e.second) {
							
							vec3* vert = nullptr;
							switch (i.y) {
								case 0: {
									point[i.x].value = f_顶点坐标移动变换(m, iv_m, 手柄要移动到是位置, v[offset]);
									++offset;

									point[i.x].L_point = f_顶点坐标移动变换(m, iv_m, 手柄要移动到是位置, v[offset]);
									++offset;

									point[i.x].R_point = f_顶点坐标移动变换(m, iv_m, 手柄要移动到是位置, v[offset]);
									++offset;
									continue;
								}
								case 1: {
									vert = &point[i.x].L_point;
									break;
								}
								case 2: {
									vert = &point[i.x].R_point;
									break;
								}
							}

							*vert = f_顶点坐标移动变换(m, iv_m, 手柄要移动到是位置, v[offset]);
							++offset;
							
						}
					}
					break;
				}
			}
		}
		else {
			if (ob[i]->m_父对象) {
				m = f_ob_get父对象变换矩阵(static_cast<S_物体*>(ob[i]->m_父对象), 0, false);
			}
			else {
				m = f_mat44_identity();
			}


			m.m30 = 0;
			m.m31 = 0;
			m.m32 = 0;
			m.m33 = 1;
			vec3 缩放 = { vec_len(m * vec3{ 1, 0, 0 }), vec_len(m * vec3{ 0, 1, 0 }), vec_len(m * vec3{ 0, 0, 1 }) };

			m = f_mat44_Invert(m);
			mat44_normalize(m);

			//std::cout<<" x = " << g手柄初始变换.position.x <<" y = " << g手柄初始变换.position.y <<" z = " << g手柄初始变换.position.z << std::endl;
			//std::cout<<" x = " << g[i].x <<" y = " << g[i].y <<" z = " << g[i].z << std::endl;

			vec3 移动矢量 = (手柄要移动到是位置 + (全局坐标[i] - g手柄初始变换.position)) - 全局坐标[i];
			//std::cout<<"移动矢量 x = " << 移动矢量.x <<" y = " << 移动矢量.y <<" z = " << 移动矢量.z << std::endl;
			//std::cout<<"移动矢量 x = " << length(移动矢量) << std::endl;
			移动矢量 = m * 移动矢量 / 缩放;

			ob[i]->f_set位置(v[i] + 移动矢量, 0);
		}
	}
	
	f_OE_移动后更新(g要变换的物体);
}

S_Tranform f_控制手柄_取消移动物体(bool 重置状态) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();


	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				uint32 offset = 0;

				for (auto& e : S_框架::g_选择端点) {
					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								point[i.x].value = v[offset];
								++offset;

								point[i.x].L_point = v[offset];
								++offset;

								point[i.x].R_point = v[offset];
								++offset;
								continue;
							}
							case 1: {
								point[i.x].L_point = v[offset];
								break;
							}
							case 2: {
								point[i.x].R_point = v[offset];
								break;
							}
						}
						++offset;
					}
				}
			}
		}
	}
	else {
		for (int32 i = 0; i < num; ++i) {
			ob[i]->f_set位置(v[i], 0);
		}
	}
	
	if (重置状态) {
		f_OE_移动后更新(g要变换的物体);
		f_控制手柄_完成变换(S_框架::g_物体变换方式);
	}

	return g手柄初始变换;
}




void f_控制手柄_准备旋转物体(S_物体* 手柄, const vec2& 鼠标局部位置, const S_Rect2Df& rect, S_摄像机* camera, bool 强制重启) {
	S_框架::g_物体变换方式;
	if (f_控制手柄_准备变换() == false && 强制重启) return;


	g手柄初始变换 = 手柄->m_变换;
	vec2 coord = f_Project空间坐标转屏幕(*(Mat44f*)&camera->m_相机投影矩阵, *(Mat44f*)&(camera->m_相机视图矩阵), g手柄初始变换.position, rect);

	vec2 鼠标移动方向 = (鼠标局部位置 - coord);
	g记录初始步进 = f_graph_两向量夹角弧度(vec_normalize2(鼠标移动方向), {1,0});
	if (鼠标移动方向.y < 0) g记录初始步进 = M_PI - g记录初始步进 + M_PI;


	

	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		for (auto 编辑物体 : S_节点数据::g_编辑物体) {
			g要变换的物体.push_back(编辑物体);
		}

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				for (auto& e : S_框架::g_选择端点) {
					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								g要变换的物体暂存位置.push_back(point[i.x].value);
								g要变换的物体暂存位置.push_back(point[i.x].L_point);
								g要变换的物体暂存位置.push_back(point[i.x].R_point);
								break;
							}
							case 1: {
								g要变换的物体暂存位置.push_back(point[i.x].L_point);
								break;
							}
							case 2: {
								g要变换的物体暂存位置.push_back(point[i.x].R_point);
								break;
							}
						}
					}
				}
			}
		}
	}
	else {
		for (auto* ob : S_框架::g_拾取物体) {
			g要变换的物体.push_back(ob);
		}


		for (auto* ob : g要变换的物体) {
			g要变换的物体暂存位置.push_back(ob->f_get位置());
			g要变换的物体暂存全局坐标.push_back(f_ob_get全局坐标(ob, ob->m_实例ID));

			Mat44f mat = f_mat44_Invert(f_ob_get父对象变换矩阵(static_cast<S_物体*>(ob->m_父对象), 0, false));
			mat.m30 = 0;
			mat.m31 = 0;
			mat.m32 = 0;
			mat.m33 = 1;
			g要变换的物体暂存矩阵.push_back(mat);

			mat = f_ob_get变换矩阵(ob, ob->m_实例ID);
			mat44_normalize(mat);
			//mat = f_mat44_Inverse(mat);
			mat = f_mat44_Invert(mat);
			mat.m30 = 0;
			mat.m31 = 0;
			mat.m32 = 0;
			mat.m33 = 1;
			g要旋转的物体暂存矩阵.push_back(mat);


			switch (f_ob_get附属类型(ob)) {
				case E_物体类型::t_摄像机: {
					auto* 摄像机 = f_ob_以类型查找子物体(ob, E_物体类型::t_摄像机);
					g要变换的物体暂存旋转.push_back(摄像机->f_get旋转());
					break;
				}
				case E_物体类型::t_包围盒: {
					g要变换的物体暂存旋转.push_back({ 0,0,0 });
					break;
				}
				default: {
					g要变换的物体暂存旋转.push_back(ob->f_get旋转());
					break;
				}
			}


			auto q = f_graph_欧拉角转四元数(ob->f_get旋转());
			g要变换的物体暂存quat.push_back(q);
		}

		f_OE_准备变换(S_框架::g_拾取物体, E_变换::e_旋转);
	}


	for (auto& e : S_框架::g_插件_变换操作) {
		if(e.second.mf_开始) e.second.mf_开始(S_框架::g_物体变换方式);
	}
}

S_Tranform f_控制手柄_视线旋转物体(vec3 旋转向量, float32 弧度, float32 方向) {
	g开启变换 = true;

	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* r = g要变换的物体暂存旋转.data();
	auto* q = g要变换的物体暂存quat.data();
	auto* 物体全局坐标 = g要变换的物体暂存全局坐标.data();
	auto* mat = g要变换的物体暂存矩阵.data();
	auto* 旋转矩阵 = g要旋转的物体暂存矩阵.data();

	vec4 rot_q = f_graph_从轴向角度计算四元数(旋转向量, (弧度 - g记录初始步进) * -方向);

	for (int32 i = 0; i < num; ++i) {
		
		if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
			
			switch (S_框架::g当前编辑对象类型) {
				case E_物体类型::t_空间曲线: {
					uint32 offset = 0;

					for (auto& e : S_框架::g_选择端点) {
						Mat44f m = f_ob_get变换矩阵(e.first, e.first->m_实例ID);
						auto iv_m = f_mat44_Invert(m);

						auto* me = f_ob_getMesh(e.first);
						auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);


						for (auto& i : e.second) {
							vec3* vert = nullptr;
							switch (i.y) {
								case 0: {
									point[i.x].value = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
									++offset;

									point[i.x].L_point = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
									++offset;

									point[i.x].R_point = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
									++offset;
									continue;
								}
								case 1: {
									vert = &point[i.x].L_point;
									break;
								}
								case 2: {
									vert = &point[i.x].R_point;
									break;
								}
							}

							(*vert) = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
							++offset;
						}
					}
					break;
				}
			}
		}
		else {
			vec3 移动矢量 = (f_graph_quat变换坐标(rot_q, 物体全局坐标[i] - g手柄初始变换.position));
			移动矢量 = mat[i] * 移动矢量;
			ob[i]->f_set位置(v[i] + ((g手柄初始变换.position + 移动矢量) - 物体全局坐标[i]), 0);

			switch (f_ob_get附属类型(ob[i])) {
				case E_物体类型::t_摄像机: {
					auto* 摄像机 = f_ob_以类型查找子物体(ob[i], E_物体类型::t_摄像机);

					vec3 rot = r[i];
					rot.z += M_弧度转角度((弧度 - g记录初始步进) * 方向);
					摄像机->f_set旋转(rot, 0);
					std::cout << "1 旋转.x = " << rot.z << " " << 弧度 - g记录初始步进 << std::endl;
					break;
				}
				case E_物体类型::t_包围盒: {
					ob[i]->f_set旋转({ 0,0,0 }, 0);
					break;
				}
				default: {
					vec3 视线向量 = (旋转矩阵[i] * 旋转向量);
					vec4 qa = f_graph_从轴向角度计算四元数(视线向量, ((弧度 - g记录初始步进)) * 方向 * DEF_ForwardDir);
					vec4 newQuat = f_graph_quat相乘(q[i], qa);

					ob[i]->f_set旋转(f_graph_四元数转欧拉角(newQuat), 0);
					break;
				}
			}
		}
	}

	f_OE_旋转后更新(g要变换的物体);

	return g手柄初始变换;
}

void f_控制手柄_局部旋转物体(E_轴向 轴向, float32 弧度) {
	g开启变换 = true;

	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* r = g要变换的物体暂存旋转.data();


	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		vec3 旋转向量;
		switch (轴向) {
			case E_轴向::e_X: 旋转向量 = { 1,0,0 }; break;
			case E_轴向::e_Y: 旋转向量 = { 0,1,0 }; break;
			case E_轴向::e_Z: 旋转向量 = { 0,0,1 }; break;
		}
		vec4 rot_q = f_graph_从轴向角度计算四元数(旋转向量, (弧度 - g记录初始步进));

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				uint32 offset = 0;

				for (auto& e : S_框架::g_选择端点) {
					Mat44f m = f_ob_get变换矩阵(e.first, e.first->m_实例ID);
					auto iv_m = f_mat44_Invert(m);

					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);


					for (auto& i : e.second) {
						vec3* vert;
						switch (i.y) {
							case 0: {
								point[i.x].value = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
								++offset;

								point[i.x].L_point = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
								++offset;

								point[i.x].R_point = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
								++offset;
								continue;
							}
							case 1: {
								vert = &point[i.x].L_point;
								break;
							}
							case 2: {
								vert = &point[i.x].R_point;
								break;
							}
						}

						(*vert) = f_顶点坐标旋转变换(m, iv_m, rot_q, v[offset]);
						++offset;
					}
				}
				break;
			}
		}
	}
	else {
		for (int32 i = 0; i < num; ++i) {
			switch (轴向) {
				case E_轴向::e_X: ob[i]->m_变换.rotation.x = r[i].x + M_弧度转角度(弧度); break;
				case E_轴向::e_Y: ob[i]->m_变换.rotation.y = r[i].y + M_弧度转角度(弧度); break;
				case E_轴向::e_Z: ob[i]->m_变换.rotation.z = r[i].z + M_弧度转角度(弧度); break;
			}
			ob[i]->m_isUpdate = true;
		}
	}
	
	S_节点数据::g_开启节点更新;

	//for (auto& e : S_框架::g_插件_变换操作) {
	//	if(e.second.mf_旋转) e.second.mf_旋转(S_框架::g_移动变换手柄, g记录初始步进, 弧度, 轴向);
	//}
}



S_Tranform f_控制手柄_取消旋转物体(bool 重置状态) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* r = g要变换的物体暂存旋转.data();


	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				uint32 offset = 0;

				for (auto& e : S_框架::g_选择端点) {
					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								point[i.x].value = v[offset];
								++offset;

								point[i.x].L_point = v[offset];
								++offset;

								point[i.x].R_point = v[offset];
								++offset;
								continue;
							}
							case 1: {
								point[i.x].L_point = v[offset];
								break;
							}
							case 2: {
								point[i.x].R_point = v[offset];
								break;
							}
						}
						++offset;
					}
				}
			}
		}
	}
	else {
		for (int32 i = 0; i < num; ++i) {
			ob[i]->f_set位置(v[i], 0);
			ob[i]->f_set旋转(r[i], 0);
		}
	}
	
	if (重置状态) {
		f_控制手柄_完成变换(S_框架::g_物体变换方式);
	}
	
	return g手柄初始变换;
}







void f_控制手柄_准备缩放物体(S_物体* 手柄, const vec2& 鼠标局部位置, const S_Rect2Df& rect, S_摄像机* camera, bool 强制重启) {
	if (f_控制手柄_准备变换() == false && 强制重启) return;


	g手柄初始变换 = 手柄->m_变换;
	vec2 coord = f_Project空间坐标转屏幕(*(Mat44f*)&camera->m_相机投影矩阵, *(Mat44f*)&camera->m_相机视图矩阵, g手柄初始变换.position, rect);
	g记录初始步进 = vec_len(鼠标局部位置 - coord);


	g要变换的物体暂存缩放.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体缩放矩阵暂存.clear();
	g要变换的物体.clear();


	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		for (auto 编辑物体 : S_节点数据::g_编辑物体) {
			g要变换的物体.push_back(编辑物体);
		}

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				for (auto& e : S_框架::g_选择端点) {
					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								g要变换的物体暂存位置.push_back(point[i.x].value);
								g要变换的物体暂存位置.push_back(point[i.x].L_point);
								g要变换的物体暂存位置.push_back(point[i.x].R_point);
								break;
							}
							case 1: {
								g要变换的物体暂存位置.push_back(point[i.x].L_point);
								break;
							}
							case 2: {
								g要变换的物体暂存位置.push_back(point[i.x].R_point);
								break;
							}
						}
					}
				}
			}
		}
	}
	else {
		for (auto& ob : S_框架::g_拾取物体) {
			g要变换的物体.push_back(ob);
			g要变换的物体暂存位置.push_back(f_ob_get全局坐标(ob, ob->m_实例ID));
			g要变换的物体暂存缩放.push_back(ob->f_get缩放());
			g要变换的物体缩放矩阵暂存.push_back(ob->m_全局缩放矩阵);
		}

		f_OE_准备变换(S_框架::g_拾取物体, E_变换::e_缩放);
	}


	for (auto& e : S_框架::g_插件_变换操作) {
		if(e.second.mf_开始) e.second.mf_开始(S_框架::g_物体变换方式);
	}

}

S_Tranform f_控制手柄_视线缩放物体(vec3 旋转向量, float32 步进) {
	g开启变换 = true;

	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();
	auto* g = g要变换的物体暂存全局坐标.data();

	步进 /= g记录初始步进;

	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		uint32 offset = 0;

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				for (auto& e : S_框架::g_选择端点) {
					Mat44f m = f_ob_get变换矩阵(e.first, e.first->m_实例ID);
					auto iv_m = f_mat44_Invert(m);

					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					vec3 dir{};
					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].value = iv_m * (g手柄初始变换.position + dir * 步进);

								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].L_point = iv_m * (g手柄初始变换.position + dir * 步进);

								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].R_point = iv_m * (g手柄初始变换.position + dir * 步进);

								break;
							}
							case 1: {
								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].L_point = iv_m * (g手柄初始变换.position + dir * 步进);
								break;
							}
							case 2: {
								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].R_point = iv_m * (g手柄初始变换.position + dir * 步进);
								break;
							}
						}
					}
				}
			}
		}
	} 
	else {
		for (int32 i = 0; i < num; ++i) {
			vec3 dir = v[i] - g手柄初始变换.position;

			ob[i]->f_set位置(g手柄初始变换.position + dir * 步进, 0);
			ob[i]->f_set缩放(s[i] * 步进, 0);
		}

		f_OE_缩放后更新(g要变换的物体);
	}


	return g手柄初始变换;
}

void f_控制手柄_局部缩放物体(E_轴向 轴向, float32 步进) {
	g开启变换 = true;

	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();
	auto* g = g要变换的物体暂存全局坐标.data();

	步进 /= g记录初始步进;

	vec3 缩放{1,1,1};
	switch (S_框架::g_操作变换轴) {
		case E_轴向::e_X: {
			缩放.x = 步进;
			break;
		}
		case E_轴向::e_Y: {
			缩放.y = 步进;
			break;
		}
		case E_轴向::e_Z: {
			缩放.z = 步进;
			break;
		}
		case E_轴向::e_XYZ: {
			缩放 = {步进,步进,步进};
			break;
		}
		default:
			break;
	}

	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		uint32 offset = 0;

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				for (auto& e : S_框架::g_选择端点) {
					Mat44f m = f_ob_get变换矩阵(e.first, e.first->m_实例ID);
					auto iv_m = f_mat44_Invert(m);

					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					vec3 dir{};
					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].value = iv_m * (g手柄初始变换.position + dir * 缩放);

								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].L_point = iv_m * (g手柄初始变换.position + dir * 缩放);

								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].R_point = iv_m * (g手柄初始变换.position + dir * 缩放);

								break;
							}
							case 1: {
								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].L_point = iv_m * (g手柄初始变换.position + dir * 缩放);
								break;
							}
							case 2: {
								dir = m * v[offset] - g手柄初始变换.position;
								++offset;
								point[i.x].R_point = iv_m * (g手柄初始变换.position + dir * 缩放);
								break;
							}
						}
					}
				}
			}
		}

		
	}
	else {
		for (int32 i = 0; i < num; ++i) {
			vec3 dir = v[i] - g手柄初始变换.position;

			ob[i]->f_set位置(g手柄初始变换.position + dir * 缩放, 0);
			ob[i]->f_set缩放(s[i] * 缩放, 0);
		}

		f_OE_变换完成();
	}

	//for (auto& e : S_框架::g_插件_变换操作) {
	//	if(e.second.mf_缩放) e.second.mf_缩放(S_框架::g_移动变换手柄, 步进, S_框架::g_操作变换轴);
	//}
}

S_Tranform f_控制手柄_全局缩放物体(E_轴向 轴向, float32 鼠标到中点距离) {
	g开启变换 = true;
	float32 步进 = 鼠标到中点距离 / g记录初始步进;

	return f_控制手柄_缩放物体(轴向, 步进);
}

S_Tranform f_控制手柄_缩放物体(E_轴向 轴向, float32 步进) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();
	auto* g = g要变换的物体暂存全局坐标.data();

	vec3 缩放{0,0,0};
	switch (S_框架::g_操作变换轴) {
		case E_轴向::e_X: {
			缩放.x = 1;
			break;
		}
		case E_轴向::e_Y: {
			缩放.y = 1;
			break;
		}
		case E_轴向::e_Z: {
			缩放.z = 1;
			break;
		}
		case E_轴向::e_XYZ: {
			缩放 = {步进,步进,步进};
			break;
		}
		default:
			break;
	}
	for (int32 i = 0; i < num; ++i) {
		vec3 dir = v[i] - g手柄初始变换.position;

		if (S_框架::g_操作变换轴 != E_轴向::e_XYZ) {
			auto rm = (f_mat44_构建XYZ旋转矩阵(ob[i]->m_变换));
			//auto 逆 = f_mat44_Invert(rm);


			//vec3 rv = 缩放;
			vec3 x = rm * vec3{1,0,0};
			vec3 y = rm * vec3{0,1,0};
			vec3 z = rm * vec3{0,0,1};

			float32 dx = fabs(dot(缩放, x));
			float32 dy = fabs(dot(缩放, y));
			float32 dz = fabs(dot(缩放, z));


			if (步进 >= 1) {
				缩放 = vec3{dx,dy,dz} * (步进 - 1) + 1;
			}
			else {
				缩放 = (1 - vec3{dx,dy,dz}) + vec3{dx,dy,dz} * 步进;
			}

		}

		ob[i]->f_set缩放(s[i] * 缩放, 0);
		ob[i]->f_set位置(g手柄初始变换.position + dir * 缩放, 0);

	}
	//f_OE_变换完成();
	return g手柄初始变换;
}

//void f_控制手柄_完成缩放物体() {
//	g要变换的物体暂存缩放.clear();
//	g要变换的物体暂存位置.clear();
//	g要变换的物体.clear();
//
//
//	f_OE_变换完成(g要变换的物体);
//	//f_global_变换手柄到物体中心();
//	f_projectFile_设置文件保存状态(false);
//	S_节点数据::g_开启节点更新 = true;
//}



S_Tranform f_控制手柄_取消缩放物体(bool 重置状态) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();


	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		uint32 offset = 0;

		switch (S_框架::g当前编辑对象类型) {
			case E_物体类型::t_空间曲线: {
				for (auto& e : S_框架::g_选择端点) {
					auto* me = f_ob_getMesh(e.first);
					auto point = f_buf_CurvePoint3D_ptr(*me->m_顶点);

					vec3 dir{};
					for (auto& i : e.second) {
						switch (i.y) {
							case 0: {
								point[i.x].value = v[offset];
								++offset;

								point[i.x].L_point = v[offset];
								++offset;

								point[i.x].R_point = v[offset];
								++offset;
								break;
							}
							case 1: {
								point[i.x].L_point = v[offset];
								++offset;
								break;
							}
							case 2: {
								point[i.x].R_point = v[offset];
								++offset;
								break;
							}
						}
					}
				}
			}
		}
	}
	else {
		for (int32 i = 0; i < num; ++i) {
			ob[i]->f_set位置(v[i], 0);
			ob[i]->f_set缩放(s[i], 0);
		}
	}
	
	if (重置状态) {
		f_控制手柄_完成变换(S_框架::g_物体变换方式);
	}
	return g手柄初始变换;
}


void f_控制手柄_完成变换(E_变换 操作类型) {
	g开启变换 = false;

	for (auto& e : S_框架::g_插件_变换操作) {
		if(e.second.mf_完成) e.second.mf_完成(操作类型);
	}

	g要变换的物体.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体暂存矩阵.clear();
	g要变换的物体暂存全局坐标.clear();

	g要旋转的物体暂存矩阵.clear();
	g要变换的物体暂存旋转.clear();
	g要变换的物体暂存quat.clear();

	g要变换的物体暂存缩放.clear();

	f_projectFile_设置文件保存状态(false);
	f_OE_变换完成();


	S_框架::g_物体变换方式 = S_框架::g_变换手柄类型;
	S_节点数据::g_开启节点更新 = true;
	//f_global_变换手柄到物体中心();
}







void f_视口控制_镜头视点移动到激活物体中心(S_摄像机& camera, const vec3& 中心) {
	
	if (S_框架::g_拾取物体.size()) {
		f_camera_set摄像机视点位置(camera, 中心);
	}
	else {
		f_camera_set摄像机视点移动到偏移点(camera);
	}
}

void f_控制手柄_移动到选中物体中心() {
	//S_框架::g_移动变换手柄->f_set位置(f_global_get激活物体包围中心点(), 0);
}

void f_控制手柄_置变换() {
	for (auto& es : S_框架::g_视口操作手柄) {
		for (auto& e : es.second) {
			e->m_变换 = S_框架::g_变换手柄属性;
			e->m_isUpdate = true;
		}
	}
}

void f_控制手柄_锁定步进位置(vec3& 步进位置, vec3 起点) {
	switch (S_框架::g_操作变换轴) {
		case E_轴向::e_X: 步进位置.y = 起点.y; 步进位置.z = 起点.z; break;
		case E_轴向::e_Y: 步进位置.x = 起点.x; 步进位置.z = 起点.z; break;
		case E_轴向::e_Z: 步进位置.x = 起点.x; 步进位置.y = 起点.y; break;

		case E_轴向::e_XY: 步进位置.z = 起点.z; break;
		case E_轴向::e_XZ: 步进位置.y = 起点.y; break;
		case E_轴向::e_YZ: 步进位置.x = 起点.x; break;
	}
}

int32 f_控制手柄_旋转视线向量(S_摄像机* camera, vec3& 视线向量) {
	if (camera->m_投影模式 == E_投影模式::e_透视) {
		视线向量 = vec_normalize2(S_射线拾取参数::g手柄初始变换 - f_camera_get眼睛位置(*camera));
	}
	else {
		视线向量 = f_camera_get视线向量(*camera);
	}

	float32 方向 = 1;
	switch (S_框架::g_操作变换轴) {
		case E_轴向::e_X:
			if (vec_dot(视线向量, vec3{ 1, 0, 0 }) < 0) 方向 = -1;
			视线向量 = vec3{ 1, 0, 0 };
			break;
		case E_轴向::e_Y:
			if (vec_dot(视线向量, vec3{ 0, 1, 0 }) < 0) 方向 = -1;
			视线向量 = vec3{ 0, 1, 0 };
			break;
		case E_轴向::e_Z:
			if (vec_dot(视线向量, vec3{ 0, 0, 1 }) < 0) 方向 = -1;
			视线向量 = vec3{ 0, 0, 1 };
			break;
		default:
			break;
	}
	return 方向;
}

void f_控制手柄_轴线显示(E_轴向 轴向) {
	return;

}

//void on_控制手柄切换(S_Props& prop) {
//	return;
//	auto* e = f_prop_Bool_1D(prop);
//	for (uint8 i = 0; i < 3; ++i) {
//		E_变换 变换方式 = E_变换(i + 1);
//		
//		if (e[i].m_Value) {
//			switch (变换方式) {
//			case E_变换::e_移动: S_框架::g_物体变换方式 = E_变换::e_移动;
//				f_变换手柄_移动手柄显示(true);
//				break;
//			case E_变换::e_旋转: S_框架::g_物体变换方式 = E_变换::e_旋转;
//				f_变换手柄_旋转手柄显示(true);
//				break;
//			case E_变换::e_缩放: S_框架::g_物体变换方式 = E_变换::e_缩放;
//				f_变换手柄_缩放手柄显示(true);
//				break;
//			}
//		}
//	}
//}

//float32 f_控制手柄_设置大小(S_物体* 变换手柄, const S_摄像机& camera) {
//	const vec3 摄像机位置 = f_camera_get眼睛位置(camera);
//	vec3 相对位置 = 摄像机位置 - S_框架::g_移动变换手柄->f_get位置();
//
//	float32 dis = fabs(vec_len(相对位置)) * 0.075;
//
//	switch (camera.m_投影模式) {
//		case E_投影模式::e_透视: {
//			f_ob_set缩放(S_框架::g_移动变换手柄, { dis, dis, dis });
//			break;
//		}
//		case E_投影模式::e_正交: {
//			f_ob_set缩放(S_框架::g_移动变换手柄, { dis, dis, dis });
//			break;
//		}
//	}
//
//	return dis;
//}



